package com.centling.smartSealForPhone.utils;

import android.util.Log;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 蓝牙指令工具类
 * Created by 13 on 2016/7/21.
 */
public class ControlUtilV2Sample {
    private byte packetHead = 0x02;
    private byte packetEnd = 0x03;
    private byte flag = 0x10;
    private byte[] updateFilebs;

    private byte[] sendLen01=intToByteArray(132);
    private byte[] sendLen02=intToByteArray(136);
    private byte[] sendLen03=intToByteArray(8);

    private byte[] beforeCmd;


    private int packetNo=1;
    private int fileLen;
    private int offset=0;

    public int s = 0;
    public int i = 1;
    public static final byte[] KEY = {(byte) 0xB4, 0x31, 0x5B, (byte) 0x86, (byte) 0x9D, 0x7D, (byte) 0xFA, (byte) 0xA2};
    public static final byte[] NEW_KEY=new byte[8];

    public ControlUtilV2Sample() {
    }

    /**
     * 新版初始化-第一步
     */
    public void init1(String mkey1, String mkey3) {
    	byte[] cmd = {0x01};//命令字
    	//封装数据域 
    	List<Byte> packet = new ArrayList<>();
    	packet.add((byte) 0x01);//初始化第一步标志位
    	/*
    	 * 将字符串转换为对应16进制字节
    	 * "b4"→ 0xb4
    	 * 因此处传入的参数为字符串，因此需要转换
    	 * 此处可改为直接传递字节数组，省去转换操作
    	 */
    	byte[] m1=new byte[8];
    	for(int i=0,j=0;i<mkey1.length();i++,j++){
			m1[j]=stringToHexInt(mkey1.substring(i, i+2));
			++i;
		}
    	byte[] m3=new byte[8];
    	for(int i=0,j=0;i<mkey3.length();i++,j++){
    		m3[j]=stringToHexInt(mkey3.substring(i, i+2));
    		++i;
    	}
    	/*
    	 * 将转换后得到的自己数组通过之前得到的新密钥进行des加密
    	 * 加密后得到16位的字节数组，取前八位，添加到数据域
    	 */
    	try {
			byte[] desm1=DesUtil.encrypt(m1, NEW_KEY);
			byte[] desm2=DesUtil.encrypt(m3, NEW_KEY);
			for(int i=0;i<8;i++){
				packet.add(desm1[i]);
			}
			for(int i=0;i<8;i++){
				packet.add(desm2[i]);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    	//将命令字与数据域进行打包发送（有数据域指令）
    	writeValue(cmd, packet);
    }
    
    /**
     * 初始化第二步
     */
    public void init2(String mkey4, String mkey3, String wkey1, String wkey2) {
    	byte[] cmd = {0x01};//命令字
    	//封装数据域，此处原理与初始化第一步相同
    	List<Byte> packet = new ArrayList<>();
    	packet.add((byte) 0x02);//初始化第二部标志位
    	byte[] m4=new byte[8];
    	for(int i=0,j=0;i<mkey4.length();i++,j++){
    		m4[j]=stringToHexInt(mkey4.substring(i, i+2));
    		++i;
    	}
    	byte[] m3=new byte[8];
    	for(int i=0,j=0;i<mkey3.length();i++,j++){
    		m3[j]=stringToHexInt(mkey3.substring(i, i+2));
    		++i;
    	}
    	byte[] m1=new byte[8];
    	for(int i=0,j=0;i<wkey1.length();i++,j++){
    		m1[j]=stringToHexInt(wkey1.substring(i, i+2));
    		++i;
    	}
    	byte[] m2=new byte[8];
    	for(int i=0,j=0;i<wkey2.length();i++,j++){
    		m2[j]=stringToHexInt(wkey2.substring(i, i+2));
    		++i;
    	}
    	try {
			byte[] desm4=DesUtil.encrypt(m1, NEW_KEY);
			byte[] desm3=DesUtil.encrypt(m2, NEW_KEY);
			byte[] desm1=DesUtil.encrypt(m2, NEW_KEY);
			byte[] desm2=DesUtil.encrypt(m2, NEW_KEY);
			for(int i=0;i<8;i++){
				packet.add(desm4[i]);
			}
			for(int i=0;i<8;i++){
				packet.add(desm3[i]);
			}
			for(int i=0;i<8;i++){
				packet.add(desm1[i]);
			}
			for(int i=0;i<8;i++){
				packet.add(desm2[i]);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    	writeValue(cmd, packet);
    }
    
    /**
     * 获取固件版本、查询硬件状态
     */
    public void getStampStatus() {
    	byte[] cmd = {0x02};//命令字
    	//打包发送指令（无数据域）
        writeValue(cmd);
    }
    
    /**
     * 设置序列号
     */
    public void setSN(String SN) {
        byte[] cmd = {0x03};
        byte[] sn = null;
        /*
         * 将字符串中的每一个字符转换为对应的ascii16进制字节码
         * 如110MS1710190005
         * 1 →  0x31
         * 整个序列号数据0x31 0x31 0x30 0x4d 0x53 0x31 0x37 0x31 0x30 0x31 0x39 0x30 0x30 0x30 0x35
         */
        try {
        	sn = SN.getBytes("ASCII");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        List<Byte> packet = new ArrayList<>();
        for (int i = 0; i < 15; i++) {

        	packet.add(sn[i]);
        }
        writeValue(cmd,packet);
    }
    
    /**
     * 获取序列号
     */
    public void getSN() {
        byte[] cmd = {0x04};
        writeValue(cmd);
    }
    
    /**
     * 设置待机时间
     */
    public void setStandby(int time) {
        byte[] cmd = {0x05};
        /*
         * 发送整数时，将整数类型转换为两个长度的16进制字节数组
         * 1  →  0x00 0x01
         * 发送时数组高低位互换发送
         * 如 0x01 0x00 顺序发送
         * 可参照开锁指令
         */
        writeValue(cmd, intToByteList(time));
    }
    
    /**
     * 获取待机时间
     */
    public void getStandby() {
        byte[] cmd = {0x06};
        writeValue(cmd);
    }
    
    /**
     * 盖章开锁(盖章)
     */
    public void stamp() {
        //用印次数是1
        byte[] cmd = {0x07};
        List<Byte> packet = new ArrayList<>();
        packet.add((byte) 0x01);
        packet.add((byte) 0x00);
        writeValue(cmd, packet);
    }
    
    /**
     * 上锁
     */
    public void lock() {
        byte[] cmd = {0x08};
        writeValue(cmd);
    }
    
    /**
     * 清空累计用章次数
     */
    public void cleanStampNum() {
        byte[] cmd = {0x09};
        writeValue(cmd);
    }
    
    /**
     * 获取累计用章次数
     */
    public void getStampNum() {
        byte[] cmd = {0x0A};
        writeValue(cmd);
    }
    
    /**
     * 换章
     */
    public void changeStamp() {
        byte[] cmd = {0x0C};
        List<Byte> packet = new ArrayList<>();
        packet.add((byte) 0x01);
        writeValue(cmd,packet);
    }
    
    /**
     * 取消换章
     */
    public void cancelChangeStamp(){
        byte[] cmd = {0x0C};
        List<Byte> packet = new ArrayList<>();
        packet.add((byte) 0x00);
        writeValue(cmd,packet);
    }

    /**
     * 老板模式
     */
    public void bossModel() {
        byte[] cmd = {0x0D};
        List<Byte> packet = new ArrayList<>();
        packet.add((byte) 0x00);
        writeValue(cmd, packet);
    }

    /**
     * 维修模式
     */
    public void repariModel() {
        byte[] cmd = {0x0D};
        List<Byte> packet = new ArrayList<>();
        packet.add((byte) 0x02);
        writeValue(cmd, packet);
    }
    
    /**
     * 工作模式
     */
    public void workModel() {
    	byte[] cmd = {0x0D};
        List<Byte> packet = new ArrayList<>();
        packet.add((byte) 0x01);
        writeValue(cmd, packet);
    }
    
    /**
     * 身份验证（连接）
     */
    public void connect(byte[] wkey2, byte[] wkey3){
    	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String date = simpleDateFormat.format(new Date(System.currentTimeMillis()));
        byte[] byteDate = hexStr2Bytes(date);
        byte[] cmd = {0x0e};
        /*
         * 身份验证指令需要发送当前时间
         * 如20171019093026 转换成对应字节 0x20 0x17 0x10 0x19 0x09 0x30 0x26
         */
        List<Byte> packet = new ArrayList<>();
        for (int i = 1; i < 8; i++) {
        	packet.add(byteDate[i - 1]);
        }
        try {
        	//此处添加的两个wkey从服务器获取，经des加密后发送给蓝牙,处理方法与初始化指令相同
			byte[] m1= DesUtil.encrypt(wkey2, NEW_KEY);
			for (int i = 1; i <= 8; i++) {
				packet.add(m1[i - 1]);
			};
			byte[] m2 = DesUtil.encrypt(wkey3, NEW_KEY);
			for (int i = 1; i <= 8; i++) {
				packet.add(m2[i - 1]);
			};
		} catch (Exception e) {
			e.printStackTrace();
		}
        writeValue(cmd, packet);
    }
    
    /**
     * 删除报警信息
     */
    public void deleteWornningInfo(){
    	byte[] cmd= {0x0f};
    	writeValue(cmd);
    }

    /**
     * 总清（清除信印上所有数据）
     */
    public void clearAll() {
        byte[] cmd = {0x11};
        writeValue(cmd);
    }

    /**
     * 升级固件
     */

    public void updataVersion(File file) {//升级指令的第一步操作，发送文件长度
    	//将文件转为字节数组
        updateFilebs = getfilebytes(file.getPath());
        //计算字节数组的长度
        fileLen = updateFilebs.length;
        /*
         * 升级指令数据域每次发送128字节的数据
         * 因此计算文件需要发送多少次
         * 如果剩余的字节数不足128，剩下的位置补0x00
         */
        s = updateFilebs.length / 128;

        Log.e("----update1---", ""+s);

        if (updateFilebs.length % 128 != 0) {
            s = s + 1;
        }
        byte[] cmd = new byte[130];
        cmd[0] = 0x1f;//命令字
        cmd[1] = 0x01;//升级命令字
        //将文件长度转为长度为4的16进制字节数组，发送时高低位互换，低位在前
        byte[] fileLen = int2bytes(updateFilebs.length);
        System.arraycopy(fileLen, 0, cmd, 6, 4);
        writeValue(cmd);
    }

    public int updateVersion2(){//升级指令的第二步操作，发送包序号为1的数据包
    	/*
    	 * 第二步开始每包数据域之间要加四字节的包序号，同样高低位互换
    	 */
        byte[] dd=new byte[133];
        dd[0]=0x02;//升级命令字
        byte[] len=int2bytes(packetNo);//包序号
        System.arraycopy(len, 0, dd, 1, 4);
        if(fileLen>128){//128字节文件数据，剩余文件长度大于128，发送数据，不足128剩下位数补0
            System.arraycopy(updateFilebs, offset, dd, 5, 128);
            offset+=128;
            fileLen-=128;
        }
        else{
            System.arraycopy(updateFilebs, offset, dd, 5, fileLen);
            offset+=fileLen;
            fileLen=0;
        }

        beforeCmd = dd;

        List<byte[]> list=new ArrayList<byte[]>();
        list = separate(makeUpdateDataPacket(dd));
        Log.e("","--------------------------------");
        for(int i=0;i<list.size();i++){
//            BluetoothLeService.WriteValue(list.get(i));
//            BluetoothLeService.isSend=false;
//            Log.e("send ", bytesToHexString(list.get(i)));
        }
        Log.e("----", "----------------------------");
        return packetNo;
    }

    /**
     * 错误或者无返回重传
     */
    public void retrainUpdate(){//发包失败的一种重传机制，可参考
        List<byte[]> list=new ArrayList<byte[]>();
        list = separate(makeUpdateDataPacket(beforeCmd));
        Log.e("----","--------------------------------");
        for(int i=0;i<list.size();i++){
            long start = System.currentTimeMillis();
//            BluetoothLeService.WriteValue(list.get(i));
//            BluetoothLeService.isSend = false;
            Log.e("send", bytesToHexString(list.get(i)));
            if(i==5){
                try{
                    Thread.sleep(20);

                }catch (Exception e){
                    e.printStackTrace();
                }
            }else {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        Log.e("----","--------------------------------");
    }

    /*
     * 升级指令第三步
     * 首先判断文件剩余字节数是否为0，字节数为0表示文件数据已经发送完毕，可以发送命令字为03的指令
     * 发送文件总校验和，验证是否升级成功
     * 如果字节数不为0，表示还有剩余的字节数据没有发送完毕，则继续进行第二部指令操作
     */
    public int updateVersion3(){
        Log.e("----update3---", ""+packetNo);
        byte[] dd=null;
        if(fileLen==0){
            dd=new byte[129];
            dd[0]=0x03;//升级命令字
            //第三部需要将第一步发送的文件长度再发送一次
            byte[] fileLen = int2bytes(updateFilebs.length);
            System.arraycopy(fileLen, 0, dd, 1, 4);
            /*
             * 计算文件总校验和
             * 方式：文件数组的所有字节进行累加
             * 最后将总和转为4字节的16进制字节数组，按照高低位互换发送
             * 注：java的byte类型为有符号数，因此大于128的字节为负数，做累加和的时候会出错
             * 因此将大于128的字节数加256得到正确的数据，再做累加和
             */
            int c=0;
            for(int i=0;i<updateFilebs.length;i++){
                c+=(updateFilebs[i]<0?updateFilebs[i]+256:updateFilebs[i]);
            }
            byte[] check=int2bytes(c);

            Log.e("---文件校验和------", bytesToHexString(check));
            System.arraycopy(check, 0, dd, 5, 4);
            List<byte[]> list=new ArrayList<byte[]>();
            list = separate(makeUpdateDataPacket03(dd));
            for(int i=0;i<list.size();i++){
//                BluetoothLeService.WriteValue(list.get(i));
                System.out.println("send "+bytesToHexString(list.get(i)));
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        else{//执行第二步
            packetNo++;
            dd=new byte[133];
            dd[0]=0x02;
            byte[] len=int2bytes(packetNo);
            System.arraycopy(len, 0, dd, 1, 4);
            if(fileLen>128){
                System.arraycopy(updateFilebs, offset, dd, 5, 128);
                offset+=128;
                fileLen-=128;
            }
            else{
                System.arraycopy(updateFilebs, offset, dd, 5, fileLen);
                offset+=fileLen;
                fileLen=0;
            }

            beforeCmd = dd;
            List<byte[]> list=new ArrayList<byte[]>();
            list = separate(makeUpdateDataPacket(dd));
            Log.e("----","----------------------------");
            for(int i=0;i<list.size();i++){
                long start = System.currentTimeMillis();
                Log.e("send", 3+"");
                if(list.get(i)!=null && bytesToHexString(list.get(i))!=null) {
//                    BluetoothLeService.WriteValue(list.get(i));
                }
//                BluetoothLeService.isSend = false;

                if(i==5){
                    try{
                        Thread.sleep(100);

                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }else {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            Log.e("----", "---------------------------");
        }
        return packetNo;
    }

    //封装发送数据（用于升级固件指令）
    private List<Byte> makeUpdateDataPacket03(byte[] dd){
        byte[] d=new byte[135];
        d[0]=0x02;
        d[1]=(byte) 0x84;
        d[2]=0x00;
        d[3]=0x1f;
        System.arraycopy(dd, 0, d, 4, dd.length);

        int checkByte=0;
        for(int i=1;i<d.length;i++){
            checkByte+=d[i];
        }
        d[133]=(byte) checkByte;
        d[134]=0x03;
        List<Byte> packet=new ArrayList<Byte>();
        for(int i=0;i<d.length;i++){
            packet.add(d[i]);
        }
        for(int i=1;i<packet.size()-1;i++){
            if(packet.get(i)==0x02||packet.get(i)==0x03||packet.get(i)==0x10){
                packet.add(i,flag);
                ++i;
            }
        }
        return packet;
    }

    
//    private List<byte[]> makePackets(List<Byte> list){
//        List<byte[]> packets=new ArrayList<byte[]>();
//        int front=list.size()/20;
//        int last=list.size()%20;
//        for(int j=0;j<front;j++) {
//            byte[] packet=new byte[20];
//            for (int i = 0; i < 20; i++) {
//                packet[i] = list.get(0);
//                list.remove(0);
//            }
//            packets.add(packet);
//        }
//        byte[] end=new byte[last];
//        for(int i=0;i<last;i++){
//            end[i]=list.get(i);
//        }
//        packets.add(end);
//        return packets;
//    }

    private byte[] getByteArrayFromFile(File file) {
        try {
            FileInputStream inputStream = new FileInputStream(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int n;
            while ((n=inputStream.read(bytes)) != -1) {
                out.write(bytes,0,n);
            }
            return out.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private byte[] getfilebytes(String pathStr) {
        InputStream is = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try {
            is = new FileInputStream(pathStr);// pathStr 文件路径
            byte[] b = new byte[1024];
            int n;
            while ((n = is.read(b)) != -1) {
                out.write(b, 0, n);
            }// end while
        } catch (Exception e) {
            Log.i("err",e.getMessage() );
        }
        return out.toByteArray();

    }

    /**
     * 整数转4位字节数组
     * @param num
     * @return
     */
    private static byte[] int2bytes(int num) {
        byte[] result = new byte[4];
        result[3] = (byte) ((num >>> 24) & 0xff);
        result[2] = (byte) ((num >>> 16) & 0xff);
        result[1] = (byte) ((num >>> 8) & 0xff);
        result[0] = (byte) ((num >>> 0) & 0xff);
        return result;
    }

    //===============================================================================
    //===============================================================================

    /**
     * 写数据 ，只需输入命令字的情况，无数据域
     *
     * @param cmd 命令字
     */
    private void writeValue(byte[] cmd) {
        writeValue(cmd, new ArrayList<Byte>());
    }

    public String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 写数据,packet已经确定的情况,
     *
     * @param packet 已经包含命令字与数据域
     */
    private void writeValue(List<Byte> packet) {
        writeValue(packet, new ArrayList<Byte>());
    }

    /**
     * 写数据，packet中不包含数据域
     *
     * @param packet
     * @param extraData 数据域
     */
    private void writeValue(List<Byte> packet, List<Byte> extraData) {
        //要发送的20字节数组
        List<byte[]> list = separate(makeDataPacket(packet, extraData));

        for (int i = 0; i < list.size(); i++) {
//            BluetoothLeService.WriteValue(list.get(i));
            Log.e("发送数据：", (bytesToHexString(list.get(i))==null?"":bytesToHexString(list.get(i))));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 写数据，需要写入命令字与数据域
     *
     * @param cmd       命令字
     * @param extraData 数据域
     */
    private void writeValue(byte[] cmd, List<Byte> extraData) {
        List<Byte> packet = new ArrayList<>();
        for (int i = 0; i < cmd.length; i++) {
            packet.add(cmd[i]);
        }
        writeValue(packet, extraData);
    }

    /**
     * 有数据时，添加数据域
     *
     * @param packet
     * @param extraData
     * @return
     */
    private List<Byte> makeDataPacket(List<Byte> packet, List<Byte> extraData) {
        //3代表 长度字两个字节+命令字一个字节，  size为数据域的长度
        byte[] length = intToByteArray(packet.size()+2+ extraData.size());
        packet.add(0, packetHead);//添加包头
        packet.add(1, length[1]);//添加长度字低位
        packet.add(2, length[0]);//添加长度字高位
        //packet[3] 为命令字
        /*
         *  数据域
        */
        if (null != extraData) {
            for (int i = 0; i < extraData.size(); i++) {
                // 这里的数字要注意
                    packet.add(i + 4, extraData.get(i));

            }
        }

        //检验字
        int checkByte = 0;
        for (int i = 1; i < packet.size(); i++) {
            checkByte += packet.get(i);
        }

//        //添加校验字
//        packet.add(packet.size(), checkDes[7]);//新
        packet.add(packet.size(), (byte)checkByte);//新
        packet.add(packet.size(), packetEnd);//添加包尾
        //校验字：从长度字到数据域最后一字节的逐字节累加值进行des加密后取低字节。
        //除包头包尾外，遇0x02、0x03、0x10在其前加标志位0x10。
        for (int i = 1; i < packet.size() - 1; i++) {
            if (packet.get(i) == 0x02 || packet.get(i) == 0x03 || packet.get(i) == 0x10) {
                packet.add(i, flag);
                ++i;
            }
        }

        return packet;
    }

    //封装数据（升级指令用）
    private List<Byte> makeUpdateDataPacket(byte[] dd){
        byte[] d=new byte[139];
        d[0]=0x02;
        d[1]=sendLen02[1];
        d[2]=sendLen02[0];
        d[3]=0x1f;
        System.arraycopy(dd, 0, d, 4, dd.length);

        int checkByte=0;
        for(int i=1;i<d.length;i++){
            checkByte+=d[i];
        }
        d[137]=(byte) checkByte;
        d[138]=0x03;

        Log.e("升级发送数据", bytesToHexString(d));

        List<Byte> packet=new ArrayList<Byte>();
        for(int i=0;i<d.length;i++){
            packet.add(d[i]);
        }
        for(int i=1;i<packet.size()-1;i++){
            if(packet.get(i)==0x02||packet.get(i)==0x03||packet.get(i)==0x10){
                packet.add(i,flag);
                ++i;
            }
        }
        return packet;
    }

    /**
     * 组装成完成的数据包
     *
     * @param packet
     * @return
     */
    private List<Byte> makeDataPacket(List<Byte> packet) {
        return makeDataPacket(packet, new ArrayList<Byte>());
    }

    public String str2HexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;

        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            sb.append(' ');
        }
        return sb.toString().trim();
    }

    public static byte[] hexStr2Bytes(String src) {
        int m = 0, n = 0;
        int l = src.length() / 2;
        System.out.println(l);
        byte[] ret = new byte[l];
        for (int i = 0; i < l; i++) {
            m = i * 2 + 1;
            n = m + 1;
            ret[i] = Byte.decode("0x" + src.substring(i * 2, m) + src.substring(m, n));
        }
        return ret;
    }

    /**
     * 将所有内容分割成20字节的数组
     * 蓝牙4.0每次只能传输20字节的数据
     * 需要将大于20字节的数据分多次发送
     * 例如一条指令有70字节，则这条指令需要传输4次才能发送完整
     *
     * @param list
     * @return
     */
    private List<byte[]> separate(List<Byte> list) {
        List<byte[]> packets = new ArrayList<>();
        int front = list.size() / 20;
        int last = list.size() % 20;
        for (int j = 0; j < front; j++) {
            byte[] packet = new byte[20];
            for (int i = 0; i < 20; i++) {
                packet[i] = list.get(0);
                list.remove(0);
            }
            packets.add(packet);
        }
        byte[] end = new byte[last];
        for (int i = 0; i < last; i++) {
            end[i] = list.get(i);
        }
        packets.add(end);
        return packets;
    }

    /**
     * 长度字
     *
     * @param i 个数
     * @return
     */
    private static byte[] intToByteArray(int i) {
        byte[] result = new byte[2];
        //由高位到低位
        result[0] = (byte) ((i>> 8) & 0xFF);
        result[1] = (byte) (i & 0xFF);
        return result;
    }
    /**
     * 待机时间
     *
     * @param i 个数
     * @return
     */
    private static List<Byte> intToByteList(int i) {
    	 List<Byte> packet = new ArrayList<Byte>();
        //由高位到低位
    	 packet.add((byte) (i & 0xFF));
    	 packet.add((byte) ((i>> 8) & 0xFF));
        return packet;
    }
    
    /**
	 * 数字字符串转换为16进制字节("01">0x01)
	 * @param str
	 * @return
	 */
    private byte stringToHexInt(String str){
		return (byte)Integer.parseInt(str, 16);
	}
	
    /**
     * 序列号后8位字节与KEY异或，生成新key
     * @param k
     * @return
     */
	public byte[] desCheck(byte[] k) {
		byte[] mk=new byte[8];
		for(int i=0; i<8; i++){
			mk[i]=(byte) (KEY[i]^k[i]);
		}
		return mk;
	}

}
